Skip to content

Fix /admin (and other routes) losing URL on page refresh#391

Open
briansmiley wants to merge 5 commits intomainfrom
fix/admin-route-param-matcher
Open

Fix /admin (and other routes) losing URL on page refresh#391
briansmiley wants to merge 5 commits intomainfrom
fix/admin-route-param-matcher

Conversation

@briansmiley
Copy link
Copy Markdown
Collaborator

@briansmiley briansmiley commented Apr 13, 2026

Summary

  • Navigating directly to /admin (URL bar, reload, bookmark) would redirect to /{cohort}/market instead of staying on the admin page
  • Root cause 1: The [cohort_name] dynamic route could capture "admin" as a cohort name during client-side routing. Fixed with a SvelteKit param matcher.
  • Root cause 2: The Kinde PKCE library stored auth tokens only in memory. Every page refresh wiped them, forcing a full OAuth redirect round-trip through Kinde back to /, which then auto-redirected to /{cohort}/market. This affected all routes but was only noticeable on non-market pages like /admin. Fixed by enabling is_dangerously_use_local_storage to persist the refresh token in localStorage, so the library can silently refresh tokens on reload without a redirect.

Changes

  • frontend/src/params/cohort.ts — new param matcher rejecting reserved names ("admin", "login")
  • frontend/src/routes/[cohort_name=cohort]/ — renamed from [cohort_name]/ to apply the matcher
  • frontend/src/lib/auth.svelte.ts — enable is_dangerously_use_local_storage on the Kinde PKCE client

Test plan

  • Refresh on /admin — should stay on admin page (no Kinde redirect flash)
  • Refresh on /{cohort}/market — should stay on market page
  • Click admin sidebar link — should still work
  • Navigate to a real cohort like /test/market — should still work
  • Log out and log back in — should work normally
  • Open in incognito / clear localStorage — first login flow should work

🤖 Generated with Claude Code

Add a SvelteKit param matcher that rejects reserved route names ("admin",
"login") so direct navigation to /admin works correctly instead of being
captured by the dynamic [cohort_name] route and redirected to /market.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@briansmiley briansmiley requested a review from a team as a code owner April 13, 2026 23:27
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
platform Ready Ready Preview, Comment Apr 14, 2026 0:18am

Request Review

On full page refresh, kinde.isAuthenticated() returns false, triggering
a login redirect through Kinde. After auth completes, Kinde returns to /
which auto-redirects to /{cohort}/market, losing the original URL. Save
the intended path in sessionStorage before the login redirect and restore
it when landing back on /.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the manual sessionStorage workaround with Kinde's built-in
mechanism. The PKCE library already saves window.location.href as
appState.kindeOriginUrl when login() is called. By providing an
on_redirect_callback, we can redirect back to the original page
(e.g. /admin) after the OAuth round-trip instead of staying on /
and getting auto-redirected to /{cohort}/market.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
window.location.replace() causes a full page reload which wipes the
Kinde PKCE in-memory token store, restarting the auth flow in a loop.
Instead, save the pre-login path to sessionStorage in the Kinde
on_redirect_callback and let the root +page.svelte restore it via
goto() (client-side navigation that preserves the token store).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Enable is_dangerously_use_local_storage so the refresh token persists
across page reloads. Without this, the Kinde PKCE library stores tokens
only in memory, forcing a full OAuth redirect round-trip on every
refresh. With persistent storage, the library silently refreshes tokens
via a background API call — no redirect, no URL loss.

This replaces the on_redirect_callback + sessionStorage workaround.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@briansmiley briansmiley changed the title Fix /admin route captured by [cohort_name] dynamic route Fix /admin (and other routes) losing URL on page refresh Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant